#include "stdafx.h"
namespace comms{

bool cData::IsEof(){
	if(Reader)return Reader->GetReadPos()>=Reader->Size();
	return true;
}
size_t cData::Size(){
	if(Reader)return Reader->Size();
	if(Writer)return Writer->Size();
	return 0; 
}
int cData::GetPos(){
	if(Reader)return Reader->GetReadPos();
	if(Writer)return Writer->GetWritePos();
	return 0; 
}
int cData::SeekCur(const int Offset){
	if(Reader){
		int ofs=Reader->GetReadPos()+Offset;
		Reader->SetReadPos(ofs);
		return ofs;
	}
	if(Writer){
		int ofs=Writer->GetWritePos()+Offset;
		Writer->SetWritePos(ofs);
		return ofs;
	}
	return 0;
}
int cData::SetPos(const int Pos){
	if(Reader)Reader->SetReadPos(Pos);
	if(Writer)Writer->SetWritePos(Pos);
	return Pos;
}
int cData::Read(void *To, const int MaxSize){
	if(Reader){
		Reader->Read(To,MaxSize);
		if(IsEof())return 0;
		else return MaxSize;
	}
	return 0;
}
void cData::Write(const void *Fm, const int Size){
	if(Writer)Writer->Write((void*)Fm,Size); 
}	
	
byte cData::ReadByte(){
	return Reader?Reader->ReadBYTE():0;
}
bool cData::ReadByte(byte *b){
	*b=Reader?Reader->ReadBYTE():0;
	return true;
}
void cData::WriteByte(const byte b){
	if(Writer)Writer->WriteBYTE(b);
}
short cData::ReadShort(){
	return Reader?Reader->ReadWORD():0;
}
bool cData::ReadShort(short *s){
	*s=Reader?Reader->ReadWORD():0;
	return true;
}
void cData::WriteShort(const short s){
	if(Writer)Writer->WriteWORD(s);
}

word cData::ReadWord(){
	return Reader?Reader->ReadWORD():0;
}
bool cData::ReadWord(word *w){
	*w=Reader?Reader->ReadWORD():0;
	return true;
}
void cData::WriteWord(const word w){
	if(Writer)Writer->WriteWORD(w);
}

int  cData::ReadInt(){
	return Reader?Reader->ReadDWORD():0;
}
bool cData::ReadInt(int *i){
	*i=Reader?Reader->ReadDWORD():0;
	return true;
}
void cData::WriteInt(const int i){
	if(Writer)Writer->WriteDWORD(i);
}

dword cData::ReadDword(){
	return Reader?Reader->ReadDWORD():0;
}
bool cData::ReadDword(dword *dw){
	*dw=Reader?Reader->ReadDWORD():false;
	return true;
}
void cData::WriteDword(const dword dw){
	if(Writer)Writer->WriteDWORD(dw);
}

float cData::ReadFloat(){
	float f=0;
	if(Reader)Reader->Read(&f,4);
	return f;
}
bool cData::ReadFloat(float *f){
	return Reader?Reader->Read(f,4)==4:false;
}
void cData::WriteFloat(float f){
	if(Writer)Writer->Write(&f,4);
}

double cData::ReadDouble(){
	double d=0;
	if(Reader)Reader->Read(&d,8);
	return d;
}
bool cData::ReadDouble(double *d){
	return Reader?Reader->Read(d,8)==8:false;
}
void cData::WriteDouble(double d){
	if(Writer)Writer->Write(&d,8);
}	
bool cData::ReadString(cStr *S, const char *Terminators){
	cAssert(S != NULL);
	cAssert(Terminators != NULL);

	S->Clear();
	bool start=false;
	do{
		char c;
		if(Read(&c,1)!=1){
			return S->Length()!=0;
		}
		if(strchr(Terminators,c)){
			if(start)break;
		}else{
			*S+=c;
			start=true;
		}
	}while(true);
	return true;
}
void cData::WriteString(const char * S){
	Write(S,strlen(S));
}
void cData::SetFilePn(const char *FilePn, bool ForWrite){
	m_FilePn = FilePn; 
	if(ForWrite)Writer=new FILE_WriteBinStream(FilePn);
	else Reader=new FILE_ReadBinStream(FilePn);
}
cData::~cData(){
	Clear();
}
void cData::Clear(){
	if(Writer)delete(Writer);
	if(Reader)delete(Reader);
	Reader=NULL;
	Writer=NULL;
}
void  BinStream::WriteBYTE(BYTE c){
    Write(&c,1);
}
void  BinStream::WriteWORD(WORD w){
	Write(&w,2);
}
void  BinStream::WriteDWORD(DWORD D){
	Write(&D,4);
}
BYTE  BinStream::ReadBYTE(){
    BYTE b=0;
	Read(&b,1);
	return b;
}
WORD  BinStream::ReadWORD(){
	WORD w=0;
	Read(&w,2);
	return w;
}
DWORD BinStream::ReadDWORD(){
	DWORD D=0;
	Read(&D,4);
	return D;
}
FILE_WriteBinStream::FILE_WriteBinStream(const char* Name){
	Pos=0;
	F=INVALID_HANDLE_VALUE;
	if(Name)F=RRewrite(Name);
	else F=RRewrite("$$$.$$$");
	TempSize=65536*128;
	TempBuffer=new BYTE[TempSize];
	TempCurrSize=0;
	TempPos=0;
}
FILE_WriteBinStream::~FILE_WriteBinStream(){
	Clear();
}
bool FILE_WriteBinStream::Valid(){
	return F!=INVALID_HANDLE_VALUE;
}
void FILE_WriteBinStream::Write(void* data,DWORD size){	
	if(F!=INVALID_HANDLE_VALUE){
		if(TempCurrSize+size>=TempSize){
			RBlockWrite(F,TempBuffer,TempCurrSize);
			TempCurrSize=0;		
		}
		if(size>TempSize)RBlockWrite(F,data,size);
		else{
			memcpy(TempBuffer+TempCurrSize,data,size);
			TempCurrSize+=size;
		}
	}
	Pos+=size;
}
DWORD FILE_WriteBinStream::Read(void* data,DWORD size){
	assert(1);
	return 0;
}
void FILE_WriteBinStream::WriteToFile(const char* Name){
	cStr From = "$$$.$$$";
	cStr To = Name;
	if(F){
		Clear();
		//comms::cIO::SetFilePermissions(To);
		//comms::cIO::RemoveFile(To);//Name);
		DeleteFile(To);//Name);
//		rename("$$$.$$$",Name);	
		rename(From.ToCharPtr(),To.ToCharPtr());
		F=INVALID_HANDLE_VALUE;
		Pos=0;
	}
}
void FILE_WriteBinStream::ReadFromFile(const char* Name){
	assert(1);
}
DWORD FILE_WriteBinStream::Size(){
    return Pos;
}
void FILE_WriteBinStream::SetReadPos(DWORD pos){
	assert(1);
}
void FILE_WriteBinStream::SetWritePos(DWORD pos){
	assert(1);
}
DWORD FILE_WriteBinStream::GetReadPos(){
	assert(1);
	return 0;
}
DWORD FILE_WriteBinStream::GetWritePos(){
	return Pos;
}
BYTE* FILE_WriteBinStream::GetData(){
	assert(1);
	return NULL;
}
void FILE_WriteBinStream::Clear(){
	if(F!=INVALID_HANDLE_VALUE && TempCurrSize)RBlockWrite(F,TempBuffer,TempCurrSize);
	if(F!=INVALID_HANDLE_VALUE)RClose(F);
	delete[]TempBuffer;	
	F=INVALID_HANDLE_VALUE;
	Pos=0;
	TempBuffer=NULL;
	TempCurrSize=0;
}
FILE_ReadBinStream::FILE_ReadBinStream(const char* Name){
	fSize=0;
	F=INVALID_HANDLE_VALUE;
	Pos=0;
	TempSize=65536*128;
	TempBuffer=new BYTE[TempSize];
	TempCurrSize=0;
	TempPos=0;
	ReadFromFile(Name);
}
FILE_ReadBinStream::~FILE_ReadBinStream(){
	if(TempBuffer)delete[]TempBuffer;
	if(F!=INVALID_HANDLE_VALUE)RClose(F);
}
bool FILE_ReadBinStream::Valid(){
	return F!=INVALID_HANDLE_VALUE;
}
void FILE_ReadBinStream::Write(void* data,DWORD size){	
	assert(1);
}
DWORD FILE_ReadBinStream::Read(void* Data,DWORD size){	
	BYTE* data=(BYTE*)Data;
	if(TempPos+size>TempCurrSize){
		DWORD rem=TempCurrSize-TempPos;
		if(rem){
			memcpy(data,TempBuffer+TempPos,rem);			
			data+=rem;
			size-=rem;
			Pos+=rem;
		}
		if(size>TempSize){
            if(F!=INVALID_HANDLE_VALUE)RBlockRead(F,data,size);
			TempCurrSize=0;
			TempPos=0;
			Pos+=size;
			return size;
		}else{
			if(F!=INVALID_HANDLE_VALUE)RBlockRead(F,TempBuffer,TempSize);
			TempCurrSize=TempSize;
			TempPos=0;
		}
	}
	memcpy(data,TempBuffer+TempPos,size);
	TempPos+=size;
	Pos+=size;
	return size;
}
DWORD FILE_ReadBinStream::Skip(DWORD size){	
	if(TempPos+size>TempCurrSize){
		DWORD rem=TempCurrSize-TempPos;
		if(rem){
			size-=rem;
			Pos+=rem;
		}
		if(size>TempSize){
			TempCurrSize=0;
			TempPos=0;
			Pos+=size;
			return size;
		}else{
			RBlockRead(F,TempBuffer,TempSize);
			TempCurrSize=TempSize;
			TempPos=0;
		}
	}	
	TempPos+=size;
	Pos+=size;
	return size;
}
void FILE_ReadBinStream::WriteToFile(const char* Name){
	assert(1);
}
void FILE_ReadBinStream::ReadFromFile(const char* Name){
	if(F!=INVALID_HANDLE_VALUE)RClose(F);
	fSize=0;
	F=INVALID_HANDLE_VALUE;
	Pos=0;
	if(Name){
		F=RReset(Name);
		if(F){			
			fSize=RFileSize(F);			
		}
	}
}
DWORD FILE_ReadBinStream::Size(){
	return fSize;
}
void FILE_ReadBinStream::SetReadPos(DWORD pos){
	assert(1);
}
void FILE_ReadBinStream::SetWritePos(DWORD pos){
	assert(1);
}
DWORD FILE_ReadBinStream::GetReadPos(){
	return Pos;
}
DWORD FILE_ReadBinStream::GetWritePos(){
	assert(1);
	return 0;
}
BYTE* FILE_ReadBinStream::GetData(){
	assert(1);
	return NULL;
}
void FILE_ReadBinStream::Clear(){
	if(TempBuffer)delete[]TempBuffer;
	if(F!=INVALID_HANDLE_VALUE)RClose(F);
	F=INVALID_HANDLE_VALUE;
	TempBuffer=NULL;
	Pos=0;
	fSize=0;
}
}